// network.h
#pragma once
#ifdef WINDOWS
#include "windows.h"
#pragma comment(lib, "Ws2_32.lib")
#endif

#include "../include/commondef.h"
#include "ethernet.h"
#include "ip.h"
#include "ppp.h"
#include "tcp.h"
#include "udp.h"

int NETWORKAPI_Ip6Addr2String(IN U8 *pu8_Ip, OUT char *pcOut);
/*将IPv6地址转换为字符串
pu8_Ip		指向16字节的IPv6地址。网络字节序。
pcOut		指向存储转换结果的缓冲区。转换结果的长度一定等于39，所以该缓冲区的长度必须大于39。
返回值		一定是0

说明：
转换结果是以0结束的。
此函数认为所有参数合法，请勿传入无效的参数。
*/

U16 NETWORKAPI_TcpCheckSum(U32 u32_Ip1, U32 u32_Ip2, char *pcTcpData, U16 u16_TcpDataLen);
/*计算基于IPv4的TCP校验和
u32_Ip1		u32_Ip1和u32_Ip2分别为源IP和目的IP，顺序可以颠倒。网络字节序。
u32_Ip2
pcTcpData	TCP层数据。包括TCP头、选项和数据。
u16_TcpDataLen	TCP层数据长度。包括TCP头、选项和数据。主机字节序。
返回值		校验和

说明：
计算TCP校验和时，先将TCP_HEADER::u16_Checksum置为0，然后调用此函数，再将返回值直接写入u16_Checksum即可，无需再做字节序转换。
校验TCP数据包时，直接调用此函数，如果返回0则表明校验成功，否则校验失败。
此函数认为所有参数合法，请勿传入无效的参数。
*/

U16 NETWORKAPI_TcpCheckSum(U8 u8_IpArry1[16], U8 u8_IpArry2[16], char *pcTcpData, U16 u16_TcpDataLen);
/*计算基于IPv6的TCP校验和
u8_IpArry1	u8_IpArry1和u8_IpArry2分别为源IP和目的IP，顺序可以颠倒。网络字节序。
u8_IpArry2
pcTcpData	TCP层数据。包括TCP头、选项和数据。
u16_TcpDataLen	TCP层数据长度。包括TCP头、选项和数据。主机字节序。
返回值		校验和

说明：
计算TCP校验和时，先将TCP_HEADER::u16_Checksum置为0，然后调用此函数，再将返回值直接写入u16_Checksum即可，无需再做字节序转换。
校验TCP数据包时，直接调用此函数，如果返回0则表明校验成功，否则校验失败。
此函数认为所有参数合法，请勿传入无效的参数。
*/

#define NETWORK_ERR_INVALID_CHUNK (CUSTOM_ERR - 1) // 输入了非法的chunk数据

int NETWORKAPI_AnalyChunk(IN char *pcIn, IN int &iLenIn, OUT int &iChunk, OUT int &iChunkLen);
/*分析一个chunk数据。不支持chunk-extension和trailer。
pcIn	输入数据，必须指向完整chunk的起始地址
iLenIn	输入数据长度。返回时变为实际读取数据的长度
iChunk	数据位置的偏移，相对pcIn。其值也等于chunk-size的长度（含CRLF）
iChunkLen	数据的长度（不含CRLF）
*/

int NETWORKAPI_HttpDechunk(IN char *pcIn, IN OUT int &iLenIn, OUT char *pcOut, IN OUT int &iLenOut);
/*解码chunk数据，直至遇到长度为0的chunk为止。不支持chunk-extension和trailer。
pcIn	输入数据，必须是chunk数据
iLenIn	输入数据长度。返回时变为实际读取数据的长度
pcOut	输出数据的缓冲区
iLenOut	输出数据的缓冲区的长度。返回时变为实际输出数据的长度

说明：如果pcOut==NULL，iLenOut返回进行Dechunk所需要的内存大小。
*/

// 过期函数。应使用SOCKETAPI_InitSocket//[
int NETWORKAPI_InitSocket();
int NETWORKAPI_CleanSocket();
//]

#define NETWORK_WARN_NOTFOUND (CUSTOM_WARN + 1) // 未找到所需数据

int NETWORKAPI_Find1stPpp(IN U8 *pu8_Data, IN OUT int &iDataLen, OUT int &iStart);
/*在串行数据中根据标志0x7E寻找第一个PPP帧。
pcData	串行数据
iDataiLen	串行数据长度，返回时变为帧长度（包括开始的0x7E标志，不包括结束的），单位字节。
iStart	返回帧的起始位置相对于pcData的偏移。
返回值：找到返回0，没找到返回NETWORK_WARN_NOTFOUND。
*/

int NETWORKAPI_CstctPppFrame(IN U8 *pu8_Data, IN int iDataLen, IN U16 u16_Proto, OUT U8 *pu8_Frame, IN OUT int &iFrameLen);
/*构造一个PPP帧。
pu8_Data	上层数据。如果为空，视为长度为零的数据。
iDataiLen	上层数据长度，单位字节。
u16_Proto	上层协议，主机字节序。
pu8_Frame	存放结果的缓冲区。
iFrameLen	存放结果的缓冲区长度，返回时变为帧长度（包括开始和结束的0x7E标志），单位字节。
*/

int NETWORKAPI_ParsePppFrame(IN U8 *pu8_Frame, IN int iFrameLen, OUT U8 *pu8_Data, IN OUT int &iDataLen, OUT U16 &u16_Proto, OUT U16 &u16_CheckSum);
/*解析一个PPP帧，得到上层数据。
pu8_Frame	PPP帧。
iFrameLen	PPP帧长度（包括开始的0x7E标志，不包括结束的），单位字节。
pu8_Data	存放结果（上层数据）的缓冲区。
iDataiLen	存放结果的缓冲区长度，返回时变为上层数据的长度，单位字节。
u16_Proto	输出上层协议，主机字节序。
u16_CheckSum	输出校验和，主机字节序。PPPGOODFCS16表示校验成功，否则失败。
*/

#define PPPINITFCS16 0xFFFF /* Initial FCS value */
#define PPPGOODFCS16 0xF0B8 /* Good final FCS value */

U16 NETWORKAPI_PPPFCS16(U16 u16_Fcs, U8 *pu8_Data, int iLen);
/*计算PPP校验和。
u16_Fcs	初始值。第一次输入时必须为PPPINITFCS16，之后每次输入上一次的结果，若要计算下一个校验和，设为PPPINITFCS16即可。
u8_Data	数据。
iLen	数据长度。
返回值：校验和。PPPGOODFCS16表示校验成功
说明：
构造一个PPP帧时，输入PPP_HEADER::u8_Addr的地址，长度截止到PPP_TAILER::u16_Checksum之前，
结果填入PPP_TAILER::u16_Checksum。
校验一个PPP帧时，输入PPP_HEADER::u8_Addr的地址，长度截止到PPP_TAILER::u16_Checksum的结束（比构造时多了2字节），
结果为PPPGOODFCS16表示校验成功，否则失败。
此函数认为所有参数合法，请勿传入无效的参数。
*/

int NETWORKAPI_FindAndParsePppFrame(IN U8 *pu8_Frame, IN OUT int &iFrameLen, OUT U8 *pu8_Data, IN OUT int &iDataLen, OUT U16 &u16_Proto, OUT U16 &u16_CheckSum);
/*寻找并解析一个PPP帧，得到上层数据。
pu8_Frame	PPP层数据。
iFrameLen	PPP层数据长度，单位字节。返回时变为已读取的字节数（如果找到，不包括结束的0x7E标志）。
pu8_Data	存放结果（上层数据）的缓冲区。
iDataiLen	存放结果的缓冲区长度，返回时变为上层数据的长度，单位字节。
u16_Proto	输出上层协议，主机字节序。
u16_CheckSum	输出校验和，主机字节序。PPPGOODFCS16表示校验成功，否则失败。
*/
